/*
 * Copyright 2010 jun.enomoto<jun.enomoto@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package foursquare4j.xml.handler;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import foursquare4j.type.Badge;
import foursquare4j.type.Beenhere;
import foursquare4j.type.Category;
import foursquare4j.type.Checkin;
import foursquare4j.type.CheckinResult;
import foursquare4j.type.Credentials;
import foursquare4j.type.Error;
import foursquare4j.type.Mayor;
import foursquare4j.type.Response;
import foursquare4j.type.Score;
import foursquare4j.type.Settings;
import foursquare4j.type.Special;
import foursquare4j.type.Stats;
import foursquare4j.type.Status;
import foursquare4j.type.Tags;
import foursquare4j.type.Tip;
import foursquare4j.type.User;
import foursquare4j.type.Venue;

public abstract class Handler<T> extends DefaultHandler {

	public abstract T getObject();

	protected String tag;

	@Override
	public void startElement(final String uri, final String localName, final String qName, final Attributes attributes) throws SAXException {
		tag = qName;
	}

	@Override
	public final void characters(final char[] ch, final int start, final int length) throws SAXException {
		characters(new String(ch, start, length));
	}

	protected void characters(final String text) throws SAXException {};

	protected void set(final Credentials credentials, final String key, final String value) {
		if ("oauth_token".equals(key)) credentials.setAccessToken(value);
		else if ("oauth_token_secret".equals(key)) credentials.setTokenSecret(value);
	}

	protected void set(final Checkin checkin, final String key, final String value) {
		if ("id".equals(key)) checkin.setId(value);
		else if ("distance".equals(key)) checkin.setDistance(value);
		else if ("display".equals(key)) checkin.setDisplay(value);
		else if ("shout".equals(key)) checkin.setShout(value);
		else if ("created".equals(key)) checkin.setCreated(value);
		else if ("timezone".equals(key)) checkin.setTimezone(value);
	}

	protected void set(final CheckinResult checkin, final String key, final String value) {
		if ("message".equals(key)) checkin.setMessage(value);
		else if ("id".equals(key)) checkin.setId(value);
		else if ("created".equals(key)) checkin.setCreated(value);
		// TODO need timezone?
	}

	protected void set(final Venue venue, final String key, final String value) {
		// FIXME id+id...?? -> use first id.
		// <venue><id>123</id>...<id>456</id>...</venue>
		if ("id".equals(key) && venue.getId() == null) venue.setId(value);
		else if ("name".equals(key)) venue.setName(value);
		else if ("distance".equals(key)) venue.setDistance(value);
		else if ("address".equals(key)) venue.setAddress(value);
		else if ("crossstreet".equals(key)) venue.setCrossstreet(value);
		else if ("city".equals(key)) venue.setCity(value);
		else if ("state".equals(key)) venue.setState(value);
		else if ("zip".equals(key)) venue.setZip(value);
		else if ("geolat".equals(key)) venue.setGeolat(value);
		else if ("geolong".equals(key)) venue.setGeolong(value);
		else if ("phone".equals(key)) venue.setPhone(value);
		else if ("twitter".equals(key)) venue.setTwitter(value);
	}

	protected void set(final User user, final String key, final String value) {
		if ("id".equals(key)) user.setId(value);
		else if ("firstname".equals(key)) user.setFirstname(value);
		else if ("lastname".equals(key)) user.setLastname(value);
		else if ("photo".equals(key)) user.setPhoto(value);
		else if ("gender".equals(key)) user.setGender(value);
		else if ("phone".equals(key)) user.setPhone(value);
		else if ("email".equals(key)) user.setEmail(value);
		else if ("twitter".equals(key)) user.setTwitter(value);
		else if ("facebook".equals(key)) user.setFacebook(value);
		else if ("friendstatus".equals(key)) user.setFriendstatus(value);
	}

	protected void set(final Mayor mayor, final String key, final String value) {
		if ("type".equals(key)) mayor.setType(value);
		else if ("checkins".equals(key)) mayor.setCheckins(value);
		else if ("message".equals(key)) mayor.setMessage(value);
		else if ("count".equals(key)) mayor.setCount(value);
	}

	protected void set(final Badge badge, final String key, final String value) {
		if ("id".equals(key)) badge.setId(value);
		else if ("name".equals(key)) badge.setName(value);
		else if ("icon".equals(key)) badge.setIcon(value);
		else if ("description".equals(key)) badge.setDescription(value);
	}

	protected void set(final Score score, final String key, final String value) {
		if ("points".equals(key)) score.setPoints(value);
		else if ("icon".equals(key)) score.setIcon(value);
		else if ("message".equals(key)) score.setMessage(value);
	}

	protected void set(final Special special, final String key, final String value) {
		if ("id".equals(key)) special.setId(value);
		else if ("kind".equals(key)) special.setKind(value);
		else if ("type".equals(key)) special.setType(value);
		else if ("message".equals(key)) special.setMessage(value);
	}

	protected void set(final Settings settings, final String key, final String value) {
		if ("sendtotwitter".equals(key)) settings.setSendtotwitter(value);
		else if ("sendtofacebook".equals(key)) settings.setSendtofacebook(value);
		else if ("pings".equals(key)) settings.setPings(value);
	}

	protected void set(final Status status, final String key, final String value) {
		if ("friendrequests".equals(key)) status.setFriendrequests(value);
	}

	protected void set(final Stats stats, final String key, final String value) {
		if ("herenow".equals(key)) stats.setHerenow(value);
		else if ("checkins".equals(key)) stats.setCheckins(value);
	}

	protected void set(final Beenhere beenhere, final String key, final String value) {
		if ("me".equals(key)) beenhere.setMe(value);
		else if ("friends".equals(key)) beenhere.setFriends(value);
	}

	protected void set(final Tip tip, final String key, final String value) {
		if ("id".equals(key)) tip.setId(value);
		else if ("text".equals(key)) tip.setText(value);
		else if ("url".equals(key)) tip.setUrl(value);
		else if ("created".equals(key)) tip.setCreated(value);
		else if ("distance".equals(key)) tip.setDistance(value);
	}

	protected void set(final Tags tags, final String key, final String value) {
		if ("tag".equals(key)) tags.add(value);
	}

	protected void set(final Error error, final String key, final String value) {
		error.setType(key);
		error.setMessage(value);
	}

	protected void set(final Response response, final String key, final String value) {
		if ("response".equals(key)) response.setMessage(value);
	}

	protected void set(final Category category, final String key, final String value) {
		if ("id".equals(key)) category.setId(value);
		else if ("fullpathname".equals(key)) category.setFullpathname(value);
		else if ("nodename".equals(key)) category.setNodename(value);
		else if ("iconurl".equals(key)) category.setIconurl(value);
	}
}